﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using ServerPlatform.Configuration;
using System.Configuration;
using DALEntities;
using MapEntities;
using System.Web.UI;
using System.Text.RegularExpressions;

namespace ServerPlatform.DataProvider
{
    public static class DataProviderFramework
    {
        private static DataProviderCollection s_Providers;
        private static object syncObj = new object();

        static DataProviderFramework()
        {
            Initialize();
        }

        public static DataProviderCollection Providers
        {
            get
            {
                return s_Providers;
            }
        }

        public static object Eval(object container, string expression)
        {
            try
            {
                return DataBinder.Eval(container, expression);
            }
            catch
            {
                return "!ERROR!";
            }
        }

        public static string Eval(object container, string expression, string format)
        {
            try
            {
                return DataBinder.Eval(container, expression, format);
            }
            catch
            {
                return "!ERROR!";
            }
        }

        public static string EvalWithFields(object container, string expression)
        {
            if (expression == null || string.IsNullOrEmpty(expression.Trim()))
                return "";
            else
            {
                StringBuilder sb = new StringBuilder(expression);
                MatchCollection fieldMatches = Regex.Matches(expression, @"{[\w\s]+}");
                foreach (Match m in fieldMatches)
                {
                    string fieldData = m.ToString().Replace("{", "").Replace("}", "");
                    string[] parts = fieldData.Split(':');
                    string fieldName, format = "{0}";
                    if (parts.Length == 1)
                        fieldName = fieldData;
                    else
                    {
                        fieldName = parts[0];
                        format = "";
                        for (int i = 1; i < parts.Length; i++)
                            format += parts[i]+ ":";
                        format = format.Remove(format.Length - 1, 1);
                            format = "{" + format + "}";
                    }
                    string fieldValue = DataProviderFramework.Eval(container, fieldName, format).Trim();
                    sb.Replace(m.ToString(), fieldValue);
                }
                return sb.ToString();
            }
        }

        public static List<ProviderInfo> GetProviders()
        {
            List<ProviderInfo> result = new List<ProviderInfo>(3);
            foreach (BaseDataProvider item in Providers)
            {
                result.Add(new ProviderInfo() { Name = item.Name, Description = item.Description, Source = item.Source });
            }
            return result;
        }

        public static BaseDataProvider GetProvider(string providerName)
        {
            return Providers[providerName];
        }

        public static ViewResult GetViewResult(ViewRequest request)
        {
            return GetProvider(request.ProviderName).GetViewResult(request);
        }

        public static Shape GetShape(string providerName, object data, ShapeItemBindingRule rule)
        {
            return GetProvider(providerName).GetShape(data, rule);
        }

        public static List<ViewSchema> GetViews(string providerName)
        {
            return GetProvider(providerName).GetViews();
        }

        private static void Initialize()
        {
            lock (syncObj)
            {
                DataProviderSection section = ConfigurationManager.GetSection("DataProviderFramework") as DataProviderSection;
                s_Providers = new DataProviderCollection();
                foreach (ProviderSettings settings in section.Providers)
                {
                    Type c = Type.GetType(settings.Type, true, true);
                    if (!typeof(BaseDataProvider).IsAssignableFrom(c))
                    {
                        throw new ArgumentException("Must be BaseDataProvider");
                    }
                    BaseDataProvider p = (BaseDataProvider)Activator.CreateInstance(c);
                    NameValueCollection parameters = settings.Parameters;
                    NameValueCollection config = new NameValueCollection(parameters.Count, StringComparer.Ordinal);
                    foreach (string str2 in parameters)
                    {
                        config[str2] = parameters[str2];
                    }
                    p.Initialize(settings.Name, config);
                    s_Providers.Add(p);
                }
            }
        }



        public static ViewSchemaList GetSchema(SchemaRequest request)
        {
            return GetProvider(request.ProviderName).GetSchema(request);
        }

        public static ViewResult[] GetViewResults(ViewRequest[] request)
        {
            List<ViewResult> result = new List<ViewResult>(3);
            foreach(ViewRequest req in request)
                result.Add(GetViewResult(req));
            return result.ToArray();
        }
    }
}


